/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package xmlopdracht2;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Vector;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.*;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.w3c.dom.DOMException;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

/**
 *
 * @author Gerben Gernaat
 */
public class Xml
{
  private File xmlFile;
  private Vector studenten;
  private org.w3c.dom.Document document;

  public Xml()
  {
  }

  public void setFile(File xmlFile)
  {
    this.xmlFile = xmlFile;
  }

  public File getFile()
  {
    return xmlFile;
  }

  public boolean validate()
  {
    try
    {
      // 1. Lookup a factory for the W3C XML Schema language
      SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");

      File schemaLocation = new File("src/xmlopdracht2/resources/Opdracht_1.xsd");
      Schema schema = factory.newSchema(schemaLocation);

      //maak een validator aan
      Validator validator = schema.newValidator();

      //maak een streamsource van het xml bestand
      Source source = new StreamSource(xmlFile);

      //het document valideren
      validator.validate(source);
      return true;
    }
    catch (Exception ex)
    {
      System.out.println(ex.getMessage());
    }

    return false;
  }

  public Vector getStudenten()
  {
    try
    {
      DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
      DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
      document = docBuilder.parse(this.xmlFile);


      // normalize text representation
      document.getDocumentElement().normalize();

      org.w3c.dom.NodeList listOfStudents = document.getElementsByTagName("Student");

      studenten = new Vector();

      for (int s = 0; s < listOfStudents.getLength(); s++)
      {
        org.w3c.dom.Node firstPersonNode = listOfStudents.item(s);
        if (firstPersonNode.getNodeType() == Node.ELEMENT_NODE)
        {
          org.w3c.dom.Element firstPersonElement = (org.w3c.dom.Element) firstPersonNode;

          String studentNr = firstPersonElement.getAttribute("StudentNr");

          // <editor-fold defaultstate="collapsed" desc="Voornaam">
          org.w3c.dom.NodeList voornaamList = firstPersonElement.getElementsByTagName("Voornaam");
          org.w3c.dom.Element voornaamElement = (org.w3c.dom.Element) voornaamList.item(0);

          org.w3c.dom.NodeList textVoornaamList = voornaamElement.getChildNodes();
          String voornaam = ((org.w3c.dom.Node) textVoornaamList.item(0)).getNodeValue().trim();
          // </editor-fold>

          // <editor-fold defaultstate="collapsed" desc="Tussenvoegsel">
          org.w3c.dom.NodeList tussenvoegselList = firstPersonElement.getElementsByTagName("Tussenvoegsel");

          org.w3c.dom.Element tussenvoegselElement = (org.w3c.dom.Element) tussenvoegselList.item(0);
          org.w3c.dom.NodeList texttussenvoegselList = tussenvoegselElement.getChildNodes();
          org.w3c.dom.Node n = (org.w3c.dom.Node) texttussenvoegselList.item(0);
          String tussenvoegsel = "";
          if (n != null)
          {
            tussenvoegsel = n.getNodeValue();
            tussenvoegsel = tussenvoegsel.trim();
          }
          // </editor-fold>

          // <editor-fold defaultstate="collapsed" desc="Achternaam">
          org.w3c.dom.NodeList achternaamList = firstPersonElement.getElementsByTagName("Achternaam");
          org.w3c.dom.Element achternaamElement = (org.w3c.dom.Element) achternaamList.item(0);

          NodeList textAchternaamList = achternaamElement.getChildNodes();
          String achternaam = ((org.w3c.dom.Node) textAchternaamList.item(0)).getNodeValue().trim();
          // </editor-fold>

          // <editor-fold defaultstate="collapsed" desc="Straatnaam">
          org.w3c.dom.NodeList straatnaamList = firstPersonElement.getElementsByTagName("Straatnaam");
          org.w3c.dom.Element straatnaamElement = (org.w3c.dom.Element) straatnaamList.item(0);

          org.w3c.dom.NodeList textStraatnaamList = straatnaamElement.getChildNodes();
          String straatnaam = ((org.w3c.dom.Node) textStraatnaamList.item(0)).getNodeValue().trim();
          // </editor-fold>

          // <editor-fold defaultstate="collapsed" desc="HuisNr">
          org.w3c.dom.NodeList huisnrList = firstPersonElement.getElementsByTagName("HuisNr");
          org.w3c.dom.Element huisnrElement = (org.w3c.dom.Element) huisnrList.item(0);

          org.w3c.dom.NodeList textHuisnrList = huisnrElement.getChildNodes();
          String huisnr = ((org.w3c.dom.Node) textHuisnrList.item(0)).getNodeValue().trim();
          // </editor-fold>

          // <editor-fold defaultstate="collapsed" desc="Postcode">
          org.w3c.dom.NodeList postcodeList = firstPersonElement.getElementsByTagName("Postcode");
          org.w3c.dom.Element postcodeElement = (org.w3c.dom.Element) postcodeList.item(0);

          org.w3c.dom.NodeList textPostcodeList = postcodeElement.getChildNodes();
          String postcode = ((org.w3c.dom.Node) textPostcodeList.item(0)).getNodeValue().trim();
          // </editor-fold>

          // <editor-fold defaultstate="collapsed" desc="Plaats">
          org.w3c.dom.NodeList plaatsList = firstPersonElement.getElementsByTagName("Plaats");
          org.w3c.dom.Element plaatsElement = (org.w3c.dom.Element) plaatsList.item(0);

          org.w3c.dom.NodeList textPlaatsList = achternaamElement.getChildNodes();
          String plaats = ((org.w3c.dom.Node) textPlaatsList.item(0)).getNodeValue().trim();
          // </editor-fold>

          // <editor-fold defaultstate="collapsed" desc="Land">
          org.w3c.dom.NodeList landList = firstPersonElement.getElementsByTagName("Land");
          org.w3c.dom.Element landElement = (org.w3c.dom.Element) landList.item(0);

          org.w3c.dom.NodeList textLandList = landElement.getChildNodes();
          String land = ((org.w3c.dom.Node) textLandList.item(0)).getNodeValue().trim();
          // </editor-fold>

          // <editor-fold defaultstate="collapsed" desc="GeboorteDatum">
          org.w3c.dom.NodeList geboortedatumList = firstPersonElement.getElementsByTagName("GeboorteDatum");
          org.w3c.dom.Element geboortedatumElement = (org.w3c.dom.Element) geboortedatumList.item(0);

          org.w3c.dom.NodeList textGeboortedatumList = geboortedatumElement.getChildNodes();
          String gb = ((org.w3c.dom.Node) textGeboortedatumList.item(0)).getNodeValue().trim();
          String date[] = gb.split("-");
          String geboortedatum = date[2] + "-" + date[1] + "-" + date[0];
          //geboortedatum = new Date();

          // </editor-fold>

          // <editor-fold defaultstate="collapsed" desc="BankrekeningNr">
          org.w3c.dom.NodeList bankrekeningnrList = firstPersonElement.getElementsByTagName("BankrekeningNr");
          org.w3c.dom.Element bankrekeningnrElement = (org.w3c.dom.Element) bankrekeningnrList.item(0);

          org.w3c.dom.NodeList textBankrekeningnrList = bankrekeningnrElement.getChildNodes();
          Integer bankrekeningnr = Integer.parseInt(((org.w3c.dom.Node) textBankrekeningnrList.item(0)).getNodeValue().trim());
          // </editor-fold>

          // <editor-fold defaultstate="collapsed" desc="Klascode">
          org.w3c.dom.NodeList klascodeList = firstPersonElement.getElementsByTagName("Klascode");
          org.w3c.dom.Element klascodeElement = (org.w3c.dom.Element) klascodeList.item(0);

          org.w3c.dom.NodeList textKlascodeList = klascodeElement.getChildNodes();
          String klascode = ((org.w3c.dom.Node) textKlascodeList.item(0)).getNodeValue().trim();
          // </editor-fold>

          Student student = new Student(studentNr, voornaam, tussenvoegsel, achternaam, straatnaam, huisnr, postcode, plaats, land, geboortedatum, bankrekeningnr, klascode);
          studenten.add(student);

        }//end of if clause
      }//end of for loop with s var
      return studenten;
    }
    catch (SAXParseException err)
    {
      System.out.println("** Parsing error" + ", line " + err.getLineNumber() + ", uri " + err.getSystemId());
      System.out.println(" " + err.getMessage());
    }
    catch (SAXException e)
    {
      Exception x = e.getException();
      ((x == null) ? e : x).printStackTrace();
    }
    catch (Throwable t)
    {
      t.printStackTrace();
    }
    return new Vector();
  }

  public Boolean changeStudent(Student student, Integer index)
  {
    try
    {
      this.studenten.setElementAt(student, index);
      NodeList list = document.getElementsByTagName("Student");
      for (int i = 0; i < list.getLength(); i++)
      {
        Node n = list.item(i);
        NamedNodeMap nnm = n.getAttributes();
        if (nnm.getNamedItem("StudentNr").getNodeValue().equals(student.getStudentNr()))
        {
          Node node = n.getFirstChild();
          while((node = node.getNextSibling()) != null)
          {
            if(node.getNodeName().equals("Voornaam"))
              node.setTextContent(student.getVoornaam());

            if(node.getNodeName().equals("Tussenvoegsel"))
              node.setTextContent(student.getTussenvoegsel());

            if(node.getNodeName().equals("Achternaam"))
              node.setTextContent(student.getAchternaam());

            if(node.getNodeName().equals("Straatnaam"))
              node.setTextContent(student.getStraatnaam());

            if(node.getNodeName().equals("HuisNr"))
              node.setTextContent(student.getHuisNr());

            if(node.getNodeName().equals("Postcode"))
              node.setTextContent(student.getPostcode());

            if(node.getNodeName().equals("Plaats"))
              node.setTextContent(student.getPlaats());

            if(node.getNodeName().equals("Land"))
              node.setTextContent(student.getLand());

            if(node.getNodeName().equals("GeboorteDatum"))
              node.setTextContent(student.getGeboorteDatum());

            if(node.getNodeName().equals("BankrekeningNr"))
              node.setTextContent(student.getBankrekeningNr().toString());

            if(node.getNodeName().equals("Klascode"))
              node.setTextContent(student.getKlascode());
          }

          break;
        }
      }
    }
    catch(DOMException dex)
    {
      return false;
    }
    
    try
    {
      // Use a Transformer for output
      TransformerFactory tFactory =
              TransformerFactory.newInstance();
      Transformer transformer = tFactory.newTransformer();

      DOMSource source = new DOMSource(document);
      StreamResult result = new StreamResult(this.xmlFile);
      transformer.transform(source, result);
      return true;
    }
    catch (TransformerConfigurationException tce)
    {
      // Error generated by the parser
      System.out.println("* Transformer Factory error");
      System.out.println("  " + tce.getMessage());

      // Use the contained exception, if any
      Throwable x = tce;
      if (tce.getException() != null)
      {
        x = tce.getException();
      }
      x.printStackTrace();
    }
    catch (TransformerException te)
    {
      // Error generated by the parser
      System.out.println("* Transformation error");
      System.out.println("  " + te.getMessage());

      // Use the contained exception, if any
      Throwable x = te;
      if (te.getException() != null)
      {
        x = te.getException();
      }
      x.printStackTrace();

    }
    return false;
  }

  public Document makeDocument(Student student)
  {
    Document doc = new Document();

    Element StudentenAdministratieElement = new Element("StudentenAdministratie");
    Element studentenElement = new Element("Studenten");

    Element studentElement = new Element("Student");
    studentElement.setAttribute("StudentNr", student.getStudentNr());

    Element voornaamElement = new Element("Voornaam");
    voornaamElement.setText(student.getVoornaam());
    studentElement.addContent(voornaamElement);

    Element tussenvoegselElement = new Element("Tussenvoegsel");
    tussenvoegselElement.setText(student.getTussenvoegsel());
    studentElement.addContent(tussenvoegselElement);

    Element achternaamElement = new Element("Achternaam");
    achternaamElement.setText(student.getAchternaam());
    studentElement.addContent(achternaamElement);

    Element straatnaamElement = new Element("Straatnaam");
    straatnaamElement.setText(student.getStraatnaam());
    studentElement.addContent(straatnaamElement);

    Element huisNrElement = new Element("HuisNr");
    huisNrElement.setText(student.getHuisNr());
    studentElement.addContent(huisNrElement);

    Element postcodeElement = new Element("Postcode");
    postcodeElement.setText(student.getPostcode());
    studentElement.addContent(postcodeElement);

    Element plaatsElement = new Element("Plaats");
    plaatsElement.setText(student.getPlaats());
    studentElement.addContent(plaatsElement);

    Element landElement = new Element("Land");
    landElement.setText(student.getLand());
    studentElement.addContent(landElement);

    Element geboortedatumElement = new Element("GeboorteDatum");
    String geboortedatum[] = student.getGeboorteDatum().split("-");
    geboortedatumElement.setText(geboortedatum[2] + "-" + geboortedatum[1] + "-" + geboortedatum[0]);
    studentElement.addContent(geboortedatumElement);

    Element bankrekeningNrElement = new Element("BankrekeningNr");
    bankrekeningNrElement.setText(student.getBankrekeningNr().toString());
    studentElement.addContent(bankrekeningNrElement);

    Element klascodeElement = new Element("Klascode");
    klascodeElement.setText(student.getKlascode());
    studentElement.addContent(klascodeElement);

    Element cijfersElement = new Element("Cijfers");
    studentElement.addContent(cijfersElement);

    studentenElement.addContent(studentElement);
    
    Element cursussenElement = new Element("Cursussen");

    Element cursusElement = new Element("Cursus");
    cursusElement.setAttribute("CursusAfkorting", "AAA");
    Element cursusNaamElement = new Element("Naam");
    cursusElement.addContent(cursusNaamElement);

    Element cursusBeschrijvingElement = new Element("Beschrijving");
    cursusElement.addContent(cursusBeschrijvingElement);

    Element cursusCursusStudentenElement = new Element("CursusStudenten");
    cursusElement.addContent(cursusCursusStudentenElement);

    cursussenElement.addContent(cursusElement);

    StudentenAdministratieElement.addContent(studentenElement);
    StudentenAdministratieElement.addContent(cursussenElement);

    doc.addContent(StudentenAdministratieElement);

    return doc;
    
  }

  public Boolean addStudent(Student student, OutputStream os)
  {
    //code voor het toevoegen van een nieuwe student
    Document doc = this.makeDocument(student);
    XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
    try
    {
      outputter.output(doc, os);
      return true;
    }
    catch (IOException ex)
    {
    }
    return false;
  }
}
